import React from 'react';
import PropTypes from 'prop-types'
import CommonUtils from '../../logics/CommonUtils';
import './BarGraph.css'

const BAR_DISTANCE = [
  ['50%'],
  ['30%', '70%'],
  ['20%', '50%', '80%'],
  ['10%', '35%', '60%', '85%'],
]

const Bar = ({ label, labelSize, value, height, left, color, decimalDigit, active }) => (
  <div
    className="Bar"
    style={{
      'left': left,
      'height': height,
    }}
  >
    <div className="barParts" style={{ backgroundColor: color }} >
      <div className="valueParts" style={{ color: color }}>
        <span className={active ? 'lage' : null} >{value.toFixed(decimalDigit)}</span><span className="small">%</span>
      </div>
      <div className="labelParts" style={{ fontSize: labelSize }}>{
        Array.isArray(label)
          ? label.map((l, idx) => <p key={idx}>{l}</p>)
          : label
      }
      </div>
    </div>
  </div>
);

const calcScale = data => {
  const sortData = Array.from(data);

  sortData.sort((a, b) => { // 降順のソート
    let aValue = a.value || 0;
    let bValue = b.value || 0;
    return bValue - aValue;
  });

  let high_value = sortData[0].value;
  let scale = 120 / high_value;
  return scale;
}

const getLowHighFixedHeight = data => {
  const fixedHeightData = data
    .filter(d => d.fixedHeight) // 高さ固定の要素のみ抽出
    .sort((a, b) => a.fixedHeight - b.fixedHeight); // 昇順ソート

  let low_value;
  let high_value;

  if (fixedHeightData.length === 0) {
    low_value = null;
    high_value = null;
  } else {
    low_value = fixedHeightData[0].fixedHeight;
    high_value = fixedHeightData[fixedHeightData.length - 1].fixedHeight;
  }

  let lowHigh = {
    low: low_value,
    hight: high_value,
  }
  return lowHigh;
}

const heightCompensation = (height, low, high) => {
  // 値の補正
  if (low && height < low)
    height = low
  if (high && height > high)
    height = high
  return height;
}

const BarGraph = ({ data, activeColor = '#d97000', inactiveColor = '#ffc983', labelSize = '0.8em', decimalDigit = 1 }) => {
  const scale = calcScale(data);
  const lowHigh = getLowHighFixedHeight(data);
  const labelLine = Math.max(...data.map(d => Array.isArray(d.label) ? d.label.length : 1));

  return (
    <div className="BarGraph" style={{ height: [
      '220px',  // ラベル1行
      '240px',  // ラベル2行
      '260px',  // ラベル3行
    ][labelLine - 1] }}>
      <div className="grid">
        {data.map((d, idx) => {
          let height = CommonUtils.getFloatFormat(d.value, decimalDigit) * scale;
          height = heightCompensation(height, lowHigh.low, lowHigh.high);

          return (
            <Bar
              key={idx}
              label={d.label}
              labelSize={labelSize}
              decimalDigit={decimalDigit}
              value={d.value}
              left={BAR_DISTANCE[data.length - 1][idx]}
              height={d.fixedHeight || height}
              color={d.active ? activeColor : inactiveColor}
              active={d.active}
            />
          )
        }, this)}
      </div>
    </div>
  )
}

BarGraph.propTypes = {
  activeColor: PropTypes.string,
  inactiveColor: PropTypes.string,
  labelSize: PropTypes.string,
  decimalDigit: PropTypes.number,
  data: PropTypes.arrayOf(
    PropTypes.shape({
      label: PropTypes.any.isRequired,
      value: PropTypes.number.isRequired,
      fixedHeight: PropTypes.number,
      active: PropTypes.boolean,
    })
  ),
};
export default BarGraph;
